#! /usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023-04-20 15:08
# @Author  : wsh
# @File    : auth_routers.py
from starlette.requests import Request

from config import SUPER_TOKEN, ROUTER_PREFIX
from model.db.mapper import add_admin
from fastapi import APIRouter, Header

from model.db.mapper.admin_mapper import admin_login
from model.db.mapper.users_mapper import get_user_by_email, get_user_by_id, update_user
from model.params.admin_params import SUPERUserLoginParam
from model.params.users_params import EmailValidateParam, PasswordByEmailParam, PasswordByLogin, UserInfoParam
from model.redis.utils import redis_verify_and_refresh_token, refresh_token, \
    redis_save_emailcode, redis_verify_email, redis_save_token
from util import success_res, obj_to_dict, SuccessCode, create_token, get_email_code, error_res, ErrorCode, \
    DataNotExist, img_util
from util.access_token import parse_token
from util.encryption import verify_pwd, bcrypt_pwd

auth_router = APIRouter()


@auth_router.post("/super_login", name="超级管理员登录")
async def _add_user(superserLoginParam: SUPERUserLoginParam, request: Request):
    admin = admin_login(superserLoginParam.username, superserLoginParam.password)
    payload = {
        "user_id": admin.user_id,
        "user_name": admin.user_name,
        "user_pwd": admin.user_pwd,
        "role_name": admin.role_name.value
    }
    token_key = SUPER_TOKEN.format(admin.user_id)
    token = await request.app.state.redis.get(name=token_key)
    if token is None:
        token = create_token(payload)
        await redis_save_token(request, admin.user_id, token, SUPER_TOKEN)
        return success_res({
            'user': obj_to_dict(admin),
            'token': token
        }, SuccessCode.LOGIN)

    await refresh_token(request, admin.user_id, token, SUPER_TOKEN)
    return success_res({
        'user': obj_to_dict(admin),
        'token': token.decode()
    }, SuccessCode.USER_LOGGED_IN)
    # SUPERredis_verify_and_refresh_token(request, payload, token, callback)

@auth_router.post("/email", name="验证邮箱验证码&&找回密码")
async def verify_email_code(email_param: EmailValidateParam, request: Request):
    user = get_user_by_email(email_param.email)
    validate = await redis_verify_email(request, user.email, email_param.email_code)

    if validate == ErrorCode.EMAIL_CODE_ERROR:
        return error_res(validate)
    if validate == ErrorCode.EMAIL_CODE_ISNONE:
        return error_res(validate)
    if validate == SuccessCode.EMAILCODE_OK:
        return success_res(obj_to_dict(user), validate)


@auth_router.post("/email/password", name="修改密码(邮箱找回密码)")
async def modify_pwd(param: PasswordByEmailParam, request: Request):
    # 再次验证邮箱
    user = get_user_by_email(param.email)
    if user is None:
        res_code = ErrorCode.DATA_NOT_EXISTED
        res_code['message'] = res_code["message"].format("用户")
        return error_res(res_code)
    validate = await redis_verify_email(request, user.email, param.email_code)
    if validate == ErrorCode.EMAIL_CODE_ERROR:
        return error_res(validate)
    if validate == ErrorCode.EMAIL_CODE_ISNONE:
        return error_res(validate)
    # 修改密码
    newUser = UserInfoParam(
        user_name=user.user_name,
        user_pwd=param.user_pwd,
        role_name=user.role_name.name,
        company_name=user.company_name,
        belong_post=user.belong_post,
        job_name=user.job_name,
        true_name=user.true_name,
        phone=user.phone,
        email=user.email,
        remark=user.remark,
        group_id=user.group_id
    )
    update_user(user.user_id, newUser)
    return success_res(obj_to_dict(user), SuccessCode.UPDATE_SUCC)


@auth_router.post("/password", name="修改密码(登录成功修改密码需要校验TOKEN）")
async def modify_pwd(param: PasswordByLogin, request: Request, token=Header("token")):
    # token合法性
    payload = parse_token(token)
    if payload.get('user_id')!=param.user_id:
        return success_res(ErrorCode.USER_NO_PERMISSION)
    user = get_user_by_id(param.user_id)
    # 验证旧密码
    if not verify_pwd(param.old_password, user.user_pwd):  # 密码错误
        return error_res(ErrorCode.OLD_PWD_ERROR)
    newUser = UserInfoParam(
        user_name=user.user_name,
        user_pwd=param.new_password,
        role_name=user.role_name,
        company_name=user.company_name,
        belong_post=user.belong_post,
        job_name=user.job_name,
        true_name=user.true_name,
        phone=user.phone,
        email=user.email,
        remark=user.remark,
        group_id=user.group_id
    )
    user = update_user(param.user_id, newUser)
    return success_res(obj_to_dict(user), SuccessCode.UPDATE_SUCC)
